package com.eastedu.superise.handler.basic;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ConcurrentHashSet;
import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.eastedu.exception.ServiceException;
import com.eastedu.manager.FileManager;
import com.eastedu.model.basic.ResourceFile;
import com.eastedu.repository.basic.mapper.BasicResourceMapper;
import com.eastedu.repository.basic.po.BasicResourcePO;
import com.eastedu.repository.file.FileOriginalMapper;
import com.eastedu.repository.file.FileOriginalPO;
import com.eastedu.repository.file.FileState;
import com.eastedu.superise.handler.AbstractFileArchiveRollbackTemplate;
import com.eastedu.util.FileUtils;
import com.eastedu.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.nio.file.Path;
import java.sql.SQLException;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 【回滚】文件归档
 * 冷存储范围：每年9月份，将五年前的 标红资源进行冷存处理，五年内的保持原来的存储方案, 排查幼儿园
 * 故事ID 90690
 *
 * @author zhangzhishuai
 */
@Slf4j
@Service
public class BasicFileArchiveRollbackHistoricalDataHandler extends AbstractFileArchiveRollbackTemplate<BasicResourcePO> {
    private static final int CLASSROOM_RECORD = 1;
    private static final int PREPARE_LESSON_RECORD = 8;
    private static final int MODEL_LESSON_RECORD = 7;
    private static final List<Integer> CATEGORIES = ListUtil.of(CLASSROOM_RECORD, PREPARE_LESSON_RECORD, MODEL_LESSON_RECORD);

    private final FileOriginalMapper fileOriginalMapper;
    private final FileInfoHistoricalDataHandler fileInfoHistoricalDataHandler;
    private final BasicResourceMapper basicResourceMapper;
    private final  ConcurrentHashSet<String> resourceIds = new ConcurrentHashSet<>();

    public BasicFileArchiveRollbackHistoricalDataHandler(FileManager fileManager,
                                                         FileOriginalMapper fileOriginalMapper,
                                                         FileInfoHistoricalDataHandler fileInfoHistoricalDataHandler,
                                                         BasicResourceMapper basicResourceMapper,
                                                         JdbcTemplate jdbcTemplate) {
        super(fileManager, jdbcTemplate);
        this.fileOriginalMapper = fileOriginalMapper;
        this.fileInfoHistoricalDataHandler = fileInfoHistoricalDataHandler;
        this.basicResourceMapper = basicResourceMapper;
    }

    @Override
    public void start() {
        super.start();
    }

    @Override
    protected String getSql() {
        return "SELECT * FROM t_basic_resource WHERE create_time < 1567267200000 and category in( 1, 8, 7) AND study_section_code = 'XQ' AND source_app_code != 'Openlearning'";
    }

    @Override
    public void callback(BasicResourcePO po) throws SQLException {
        Set<String> fileIds = JsonUtil.parseList(po.getFilesJson(), ResourceFile.class)
                .stream()
                .filter(resourceFile -> "mp4".equalsIgnoreCase(resourceFile.getExtension()))
                .map(ResourceFile::getFileId)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet());

        for (String fileId : fileIds) {
            try {
                FileOriginalPO fileInfo = fileOriginalMapper.selectById(fileId);
                // 只处理已归档的文件
                if (!Objects.equals(fileInfo.getState(), FileState.ARCHIVED)) {
                    log.error("{}:文件不是已归档状态，当前状态为：{}", fileId, fileInfo.getState());
                    break;
                }
                Path originalFilePath = download(fileId, fileInfo);
                upload(fileInfo, originalFilePath);
                updateResourceByFileId(fileId);
                FileUtils.deletePath(originalFilePath);

            } catch (Exception e) {
                log.error("{}:查询文件信息异常：{}", fileId, e.getMessage(), e);
                resourceIds.add(String.valueOf(po.getId()));
            }
        }
        if (CollUtil.isNotEmpty(resourceIds)) {
            log.info("文件回滚失败的资源ID: {}", this.resourceIds);
        }
    }

    private void updateResourceByFileId(String fileId) {
        List<BasicResourcePO> basicResources = basicResourceMapper.selectList(Wrappers.lambdaQuery(BasicResourcePO.class).apply("JSON_CONTAINS(files_json, JSON_OBJECT('fileId',{0}))", fileId));
        basicResources.forEach(po -> {
            try {
                this.fileInfoHistoricalDataHandler.callback(po);
            } catch (SQLException e) {
                throw new ServiceException(e, "文件更新异常");
            }
        });
    }

    @Override
    public void afterCompletion() {
        super.afterCompletion();
        log.info("文件归档失败的资源id: {}", this.resourceIds);
    }

}
